/*----------------------------------------------------------------------------------------
*
*  Copyright 2019, Gao Hai Hui, <fromzeropoint@126.com>.  All rights reserved.
*  https://gitee.com/helloworldghh/xoskit.git
*  Use of this source code is governed by a MIT license
*  that can be found in the License file.
*
----------------------------------------------------------------------------------------*/
#ifndef __IMPL_SSL_IMPL_H__
#define __IMPL_SSL_IMPL_H__

#include "include_openssl.h"
#include "../tools/head.h"

namespace xos_encrypt
{

    class ssl_mgr;

    class ssl_impl : public xos_stl::mem_item< xos::release_impl< ssl_impl >, thread_lock >,
        public i_ssl
    {
    public:
        enum enumState
        {
            STATE_NONE,
            STATE_WAIT_FOR_CONNECT,
            STATE_CONNECT,
            STATE_NORMAL,
            STATE_SHUTDOWN
        };
    public:
        typedef xos::release_impl< ssl_impl > T;

    public:
        /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
        //
        static int get_xos_item_data( ITEM_DATA *& item_ptr );

    public:
        ssl_impl();
        ~ssl_impl();

    protected:
        xos_box::i_buf * m_pWriteBuf;
        xos_box::i_buf * m_pReadBuf;

        BUF_MEM m_write_buf;
        BUF_MEM m_read_buf;

        BIO * m_pWriteBIO;
        BIO * m_pReadBIO;

        enumState m_eState;
        SSL * m_pSSL;

    protected:
        ssl_mgr * m_pMgr;

    protected:
        int get_data_from_write_bio( xos_box::i_list * pOut );
        int show_error_info( int nRet ) const;
        int write_error( int nRet );
        int read_error( int nRet ) const;
        int init_null_mem( BUF_MEM * pMem );
        bool empty_mem( BUF_MEM * pMem );
        int init_mem( BUF_MEM * pMem );
        int term_mem( BUF_MEM * pMem );
        int init_data();

    public:
        int set_mgr( ssl_mgr * pMgr );
        int init();
        int term();

    public:
        // 
        // decode说明：
        //  1 : 初始状态，是接收对方shakehand包的。此时生成的返回握手包在pSendBack中，需立刻发给对方
        //  2 : 正常状态，解密，生成数据在pOut中。
        //  3 : 正常状态，收到对方的close_notify，此时生成返回确认包，在pSendBack中，需立刻发给对方
        // 
        //  0 : 解密成功
        // -1 : 解密失败，协议或数据错误
        //  2 : 连接成功
        // -2 : 连接失败，协议或数据错误。服务端接受连接时才会发生，可以利用它来切换到非ssl的明文协议状态
        //  3 : 连接断开
        // -4 : 写入BIO失败，不太可能
        int decode( xos_box::i_list * pIn, xos_box::i_list * pOut, xos_box::i_list * pSendBack );

        // 
        // encode说明：
        // 
        //  1 : 初始状态，且pIn为空，表示想建立连接，pOut中为生成的shakehand包
        //  2 : 正常连接，且pIn非空，当然是加密数据，pOut中为加密后的数据
        //  3 : 正常连接，且pIn为空，表示要断开连接，pOut中为生成的shutdown包
        // 
        // 生成的数据包都直接发送给对方
        // 
        //  0 : 成功，可能是：生成shakehand包成功，加密数据成功，生成shutdown包成功。
        // -1 : 失败，不可能出现失败，这个方法永远成功
        // 
        int encode( xos_box::i_list * pIn, xos_box::i_list * pOut );

        // 初始化
        int init_ssl();
    };

} // xos_encrypt

#endif // __IMPL_SSL_IMPL_H__
